#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

#include "common.h"

static void* ThreadWork(void* arg)
{	
		struct recvData *recvDataBak = NULL;
		struct recvData *recvDataTmp = NULL;
		struct timespec ts;
		struct timeval  tv;		
		struct internalTask *pIT = (struct internalTask *)arg;			

		while( !IsExit() )
		{
				gettimeofday(&tv, NULL); 
				
			  ts.tv_sec  = tv.tv_sec + 2;
		    ts.tv_nsec = tv.tv_usec * 1000;		
		    
		    if( sem_timedwait(&(pIT->taskSem),&ts) != 0 )	continue;	
		    
		    pthread_mutex_lock(&(pIT->Lock)); 
				recvDataTmp = pIT->recvData;
				pIT->recvData = NULL;
				pthread_mutex_unlock(&(pIT->Lock));		

				while( recvDataTmp != NULL )
				{
						pIT->pCallBack(recvDataTmp);
						
						recvDataBak = recvDataTmp;
						recvDataTmp = recvDataTmp->pNext;
						recvDataBak->pNext = NULL;
						RecoveryChain(recvDataBak);							
				}
		}		
	
		return 0;
}

struct internalTask *createTask(void(*pCallBack)(struct recvData *))
{
		pthread_t ptID;
		struct internalTask *itTemp;
		
		if( ( itTemp = (struct internalTask *)malloc(sizeof(struct internalTask)) ) == NULL )	
		{
				return NULL;	
		}		
		
		itTemp->pCallBack = pCallBack;
		itTemp->recvData  = NULL;
		
		if( pthread_mutex_init (&(itTemp->Lock),NULL) != 0   ) 
		{
				printf("pthread_mutex_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}
		
		if( sem_init(&(itTemp->taskSem), 1, 0) != 0   ) 
		{
				printf("sem_init failure {%s(%d)}\n",__FILE__,__LINE__);	
				return NULL;
		}	
						
		if( pthread_create(&ptID, NULL, ThreadWork, (void *)itTemp) != 0 )
		{
				printf("Make thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return NULL;
		}		
	
		return itTemp;
}

void PushTask(struct internalTask *pIT,struct recvData *src)
{
    pthread_mutex_lock(&(pIT->Lock)); 
		InsertTail(&(pIT->recvData),src);
		pthread_mutex_unlock(&(pIT->Lock));	
		
		sem_post(&(pIT->taskSem));
}


